/*-------------------------------------------------------------------------
 *
 * memdebug.c
 *	  在内存上下文实现中使用的声明，不是内存管理子系统的公共 API 的一部分。
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/backend/utils/mmgr/memdebug.c
 *
 *
 *	关于 CLOBBER_FREED_MEMORY:
 *
 *	如果定义了该符号，则所有被释放的内存会被用 0x7F 覆盖。
 *	这对于捕捉引用已经释放的内存的地方非常有用。
 *
 *	关于 MEMORY_CONTEXT_CHECKING:
 *
 *	由于我们通常将请求的大小向上舍入到下一个 2 的幂，因此在请求的数据区之后
 *	通常会有一些未使用的空间。因此，如果有人在他们请求的内存之后写入常见的错误，
 *	这个问题很可能不会被注意到...，直到某一天当没有任何浪费空间的时候，也许是因为
 *	新的平台上不同的内存对齐，或其他影响。为了捕捉这种类型的问题，MEMORY_CONTEXT_CHECKING
 *	选项会在请求的空间小于实际块大小的情况下，在请求的空间之后存储 0x7E，并在释放块
 *	时验证该字节是否未损坏。
 *
 *
 *	关于 USE_VALGRIND 和 Valgrind 客户端请求：
 *
 *	Valgrind 提供了“客户端请求”宏，与主机 Valgrind 交换信息（如果有的话）。在 !USE_VALGRIND 下，
 *	memdebug.h 会模拟当前使用的宏。
 *
 *	在 Valgrind 下运行时，我们希望分配之前和之后都有一个 NOACCESS 内存区域。块头是作为
 *	前导区域的诱惑，但 mcxt.c 期望能够检查标准块头字段。因此，我们在可用时使用 requested_size 字段和
 *	任何后续填充。在返回块指针给调用者之前，requested_size 会被设置为 NOACCESS。然而，为了减少
 *	客户端请求流量，它保持在空闲列表上的块中为 DEFINED。
 *
 *	块的向上舍入容量通常充当分配后的 NOACCESS 区域。如果请求恰好消耗了整个块，则不存在这样的区域；
 *	另一个块头可能会紧随其后。在这种情况下，Valgrind 不会检测到对块末尾的访问。
 *
 *	有关 mcxt.c 中的协作 Valgrind 客户端请求，请参见。
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "utils/memdebug.h"

#ifdef RANDOMIZE_ALLOCATED_MEMORY

/*
 * 用“随机”数据填充一个刚分配的内存块。其实并不是真正的
 * 随机，只是一个长度为质数的重复序列。我们主要希望
 * 从中获得的是，两个相同字节数的 palloc 起始时包含不同的数据的
 * 概率较高。
 *
 * 该区域可能为 NOACCESS，因此首先将其设置为 UNDEFINED，以避免在
 * 填充时出现错误。填充区域会使其变为 DEFINED，因此之后
 * 再次将其设置为 UNDEFINED。最后将其设置为 UNDEFINED
 * 还是 NOACCESS 是相当任意的。UNDEFINED 对于 SlabRealloc() 来说更为方便，
 * 而其他调用者没有偏好。
 */
void randomize_mem(char *fc_ptr, size_t fc_size)
{
	static int	fc_save_ctr = 1;
	size_t		fc_remaining = fc_size;
	int			fc_ctr;

	fc_ctr = fc_save_ctr;
	VALGRIND_MAKE_MEM_UNDEFINED(fc_ptr, fc_size);
	while (fc_remaining-- > 0)
	{
		*fc_ptr++ = fc_ctr;
		if (++fc_ctr > 251)
			fc_ctr = 1;
	}
	VALGRIND_MAKE_MEM_UNDEFINED(fc_ptr - fc_size, fc_size);
	fc_save_ctr = fc_ctr;
}

#endif							/* 随机化已分配的内存 */
